package com.friend.uu;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;

import java.io.File;
import java.io.FileFilter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;

public class EncryptActivity extends Activity implements View.OnClickListener, AdapterView.OnItemClickListener {
    private EncryptUtils encryptUtil;
    private TextView tv_path;
    private EditText et_key;
    private Button btn_encrypt, btn_decrypt;
    private static final int END_CODE = 456;
    private String[] sdPaths;
    private String[] appStoragePaths;
    private final Handler mHandler = new MyHandler(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_encrypt);

        encryptUtil = new EncryptUtils(mHandler, END_CODE);
        bindView();
        init();
    }

    private void bindView() {
        btn_decrypt = findViewById(R.id.btn_encrypt);
        btn_decrypt.setOnClickListener(this);
        btn_encrypt = findViewById(R.id.btn_decrypt);
        btn_encrypt.setOnClickListener(this);
        findViewById(R.id.btn_help).setOnClickListener(this);
        findViewById(R.id.btn_encrypt_back).setOnClickListener(this);

        ((ListView) findViewById(R.id.lv_fileBrowse)).setOnItemClickListener(this);

        tv_path = findViewById(R.id.tv_path);
        tv_path.setEllipsize(TextUtils.TruncateAt.MARQUEE);//文件路径走马灯显示
        et_key = findViewById(R.id.et_key);
        et_key.setFocusableInTouchMode(true);
    }

    private void init() {
        //获取相关路径
        sdPaths = getSdPaths();
        appStoragePaths = getAppStoragePaths();
        //读取数据文件
        String DEFAULT_FOLDER = "YJiaMi";
        File defaultDir = new File(Environment.
                getExternalStorageDirectory(), DEFAULT_FOLDER);
        if (!defaultDir.exists()) //noinspection ResultOfMethodCallIgnored
            defaultDir.mkdir();
        updateListView(defaultDir, false);
    }

    @Override//ListView onItemClick
    public void onItemClick(AdapterView<?> parent, View view, int position,
                            long id) {
        ListView lv = findViewById(R.id.lv_fileBrowse);
        String s = (String) lv.getItemAtPosition(position);
        String tvText = tv_path.getText().toString();

        if (s.equals("/..")) {
            for (String item : sdPaths) {
                if (tvText.equals(item)) {
                    updateListView(null, true);
                    return;
                }
            }
            for (String item : appStoragePaths) {
                if (tvText.equals(item)) {
                    updateListView(null, true);
                    return;
                }
            }
            updateListView(new File(tvText).getParentFile(), false);
            return;
        }

        if (new File(tvText, s).isDirectory()) {
            updateListView(new File(tvText, s), false);
        }
        //"SdCard*"
        if (s.startsWith("SdCard") && s.length() == 7) {
            updateListView(new File(sdPaths[Integer.parseInt(s.substring(6))]),
                    false);
        }
        //AppStoragePath*
        if (s.startsWith("AppStoragePath") && s.length() == 15) {
            updateListView(new File(appStoragePaths[Integer.parseInt(s.substring(14))])
                    , false);
        }
    }

    private String[] getSdPaths() {
        ArrayList<String> pathList = new ArrayList<>();
        String path = Environment.getExternalStorageDirectory().getAbsolutePath();
        pathList.add(path);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            StorageManager sm = (StorageManager) getSystemService(STORAGE_SERVICE);
            if (sm != null) {
                for (StorageVolume sv : sm.getStorageVolumes()) {
                    try {
                        @SuppressWarnings("JavaReflectionMemberAccess")
                        Object o = sv.getClass().getMethod("getPath").invoke(sv);
                        if (o != null && !path.equals(o.toString())) {//外卡
                            pathList.add(o.toString());
                        }
                    } catch (Exception e) {
                        Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
                    }
                }
            }
        }
        return pathList.toArray(new String[0]);
    }

    private String[] getAppStoragePaths() {
        ArrayList<String> paths = new ArrayList<>();
        File dir = getExternalFilesDir(null);
        if (dir == null) return null;
        paths.add(dir.getAbsolutePath());
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
            return new String[]{dir.getAbsolutePath()};
        for (File dir1 : getExternalFilesDirs(null)) {
            if (!dir.equals(dir1)) {
                paths.add(dir1.getAbsolutePath());
            }
        }
        return paths.toArray(new String[0]);
    }

    private void updateListView(File dir, boolean isBoot) {
        ListView lv = findViewById(R.id.lv_fileBrowse);
        MyListAdapter adapter;
        ArrayList<String> listStr;
        if (isBoot) {
            tv_path.setText(R.string.bootPath);
            btn_encrypt.setEnabled(false);
            btn_decrypt.setEnabled(false);
            listStr = new ArrayList<>();
            for (int i = 0; i < appStoragePaths.length; i++) {
                listStr.add("AppStoragePath" + i);
            }
            for (int i = 0; i < sdPaths.length; i++) {
                listStr.add("SdCard" + i);
            }
            adapter = new MyListAdapter(this, dir, listStr);
            lv.setAdapter(adapter);
            return;
        }
        //非根目录
        tv_path.setText(dir.getAbsolutePath());
        listStr = new ArrayList<>();
        File[] fs = dir.listFiles();
        if (fs == null) return;
        File[] folders = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {
                return file.isDirectory();
            }
        });
        File[] files = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {
                return file.isFile();
            }
        });
        listStr.add("/..");
        if (files != null) {
            btn_decrypt.setEnabled(files.length > 0);
            btn_encrypt.setEnabled(files.length > 0);
            for (File f : files) {
                listStr.add(f.getName());
            }
        }
        if (folders != null) {
            for (File folder : folders) {
                listStr.add(folder.getName());
            }
        }
        adapter = new MyListAdapter(this, dir, listStr);
        lv.setAdapter(adapter);
    }

    private class MyListAdapter extends ArrayAdapter<String> {
        File dir;

        public MyListAdapter(Context context, File dir, ArrayList<String> values) {
            super(context, R.layout.layout_list_item, values);
            this.dir = dir;
        }

        @NonNull
        @Override
        public View getView(int position, View convertView, @NonNull ViewGroup parent) {
            MarqueeTextView tv;
            if (convertView == null) {
                LinearLayout ly = new LinearLayout(getContext());
                tv = new MarqueeTextView(getContext());
                ly.addView(tv);
                convertView = ly;
                convertView.setTag(tv);
            } else {//这里的tv就相当于简化版ViewHolder
                tv = (MarqueeTextView) convertView.getTag();
            }
            String str = getItem(position);
            tv.setText(str);
            assert str != null;
            int imageId = new File(dir, str).isFile() ?
                    R.drawable.ic_file : R.drawable.ic_folder;
            Drawable drawableLeft = getResources()
                    .getDrawable(imageId);
            tv.setCompoundDrawablesWithIntrinsicBounds(drawableLeft,
                    null, null, null);
            return convertView;
        }
    }

    @Override
    public void onClick(View v) {
        final File dir = new File(tv_path.getText().toString());
        File[] files = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {
                return file.isFile();
            }
        });
        final String sKey = et_key.getText().toString();
        switch (v.getId()) {
            case R.id.btn_help:
                if (dir.exists()) updateListView(dir, false);
                AlertDialog.Builder dialog = new AlertDialog.Builder(this);
                dialog.setMessage(R.string.encrypt_help);
                dialog.setPositiveButton(android.R.string.ok, null);
                dialog.show();
                break;
            case R.id.btn_encrypt:
            case R.id.btn_decrypt:
                if (files == null) return;
                v.setEnabled(false);
                if (v.getId() == R.id.btn_encrypt) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            encryptUtil.encryptDir(dir, sKey);
                        }
                    }).start();
                } else {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            encryptUtil.decryptDir(dir, sKey);
                        }
                    }).start();
                }
                break;
            case R.id.btn_encrypt_back:
                finish();
                break;
        }
    }

    private void handleMsg(String msg) {

        btn_decrypt.setEnabled(true);
        btn_encrypt.setEnabled(true);
        Toast.makeText(EncryptActivity.this,
                msg, Toast.LENGTH_LONG).show();
        updateListView(new File(tv_path.getText().toString()), false);
    }

    static class MyHandler extends Handler {
        private final WeakReference<EncryptActivity> eActivity;

        MyHandler(EncryptActivity ea) {
            eActivity = new WeakReference<>(ea);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            EncryptActivity ea = eActivity.get();
            if (ea != null) {
                super.handleMessage(msg);
                if (msg.what == END_CODE) {
                    ea.handleMsg(msg.obj.toString());
                }
            }
        }
    }
}
